﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using huqiang.Communication;

namespace huqiang.FileTool
{
    public class VirtualFileWriter
    {
        VirtualFileInfo fileInfo;
        public string Folder { get; private set; }
        public string Name { get; private set; }

        public VirtualFileWriter(string folder)
        {
            folder = folder.Replace('\\', '/').ToLower();
            int s = folder.LastIndexOf('/');
            if(s>=0)
            {
                Folder = folder.Substring(0, s);
                s++;
                string n = folder.Substring(s, folder.Length - s);
                Name = n.Split('.')[0];
            }
            else
            {
                Name = folder.Split('.')[0];
            }
            // .vf
            fileInfo = new VirtualFileInfo();
            fileInfo.name = Name;
            fileInfo.subset = new List<VirtualFileInfo>();
            string[] files = Directory.GetFiles(folder,"*.*",SearchOption.AllDirectories);
            string dic = folder + "/";
            if(files!=null)
            {
                for (int i = 0; i < files.Length; i++)
                {
                    string path = files[i].Replace('\\','/').ToLower();
                    string key = path.Replace(dic,"");
                    AddRealFile(key, path);
                }
            }
        }
        public VirtualFileInfo Find(string key)
        {
            if (fileInfo == null)
                return null;
            string[] tree = key.Split('/');
            int c = tree.Length - 1;
            VirtualFileInfo vfi = fileInfo;

            for (int i = 0; i < tree.Length; i++)
            {
                var t = vfi.subset.Find((o) => { return o.name == tree[i]; });
                if (t == null)
                {
                    return null;
                }
                vfi = t;
            }
            return vfi;
        }
        public void Write(string path)
        {
            if (File.Exists(path))
                File.Delete(path);
            using (var fs = File.Create(path))
            {
               for(int i=0;i< fileInfo.subset.Count;i++)
                    WriteSubset(fs, fileInfo.subset[i],"");
            }
        }
        void WriteSubset(FileStream fs,VirtualFileInfo fileInfo,string rp)
        {
            rp = rp + "/" + fileInfo.name;
            if (File.Exists(fileInfo.realPath))
            {
                byte[] kd = Encoding.UTF8.GetBytes(fileInfo.key);
                byte[] buf = kd.Length.ToBytes();
                byte[] dat = File.ReadAllBytes(fileInfo.realPath);
                byte[] buf2 = dat.Length.ToBytes();
                fs.Write(buf,0,4);
                fs.Write(buf2,0,4);
                fs.Write(kd,0,kd.Length);
                fs.Write(dat,0,dat.Length);
            }
            if(fileInfo.subset!=null)
            {
                for (int i = 0; i < fileInfo.subset.Count; i++)
                    WriteSubset(fs,fileInfo.subset[i],rp);
            }
        }
        void AddRealFile(string key,string path)
        {
            //key = key.Replace('\\','/');
            string[] tree = key.Split('/');
            int c = tree.Length - 1;
            VirtualFileInfo vfi = fileInfo;

            for (int i = 0; i < tree.Length; i++)
            {
                var t = vfi.subset.Find((o) => { return o.name == tree[i]; });
                if (t == null)
                {
                    t = new VirtualFileInfo();
                    t.name = tree[i];
                    t.subset = new List<VirtualFileInfo>();
                    vfi.subset.Add(t);
                }
                vfi = t;
            }
            vfi.realPath = path;
            vfi.key = key;
        }
    }
}
